<?php

/**
 * Trình bày bảng dữ liệu
 *
 * @author luunguyen
 * @since Dec 24, 2012 - 2:30:40 PM
 */
class DataTable extends CWidget
{

    public $model; // Model của đối tượng trình bày
    public $title         = ''; // Tiêu đề của bảng dữ liệu
    public $columns       = array(); // Các cột sẽ hiển thị
    public $autoAttrLimit = 8; // Số cột sẽ trình bày tự động trong trường hợp không chỉ định cột cụ thể
    public $limitArray    = array(10, 20, 30, 50, 100, 500, 1000);
    public $limit         = 10; // Số bản ghi hiển thị trên 1 trang mặc định
    public $currentLimit; // Số bản ghi hiển thị trên 1 trang đang áp dụng
    public $route         = ''; // Route của tragn hiện tại
    public $maxPageButton = 5; // Số trang hiển thị tối đa trên dòng phân trang
    public $tableClass    = 'table table-striped table-mod-2'; // Class của bảng bao lấy danh sách phần tử
    public $controller; // Đối tượng Controller đang sử dụng widget này
    public $sort; // Thuộc tính được sắp xếp
    public $currentSort; // Thuộc tính được sắp xếp hiện tại
    public $sortType; // Kiểu sắp xếp asc và desc
    public $currentSortType; // Kiểu sắp xếp hiện tại
    public $fieldSearch; // Trường dùng để tìm kiếm
    public $noAction      = FALSE; // Không dùng các action
    public $noPaging      = FALSE; // Không dùng phân trang
    public $noSort        = FALSE; // Không dùng tính năng sắp xếp
    public $htmlOptions   = array(); // Các thuộc tính cho thẻ chứa
    public $linkViewMore  = ""; // Hiển thị link xem đầy đủ
    public $linkCreate    = ""; // Hiển thị link xem đầy đủ
    public $with          = array(); // Relation

    public function init()
    {
        parent::init();

        /**
         * Trường hợp không truyền vào các thuộc tính hiển thị
         * Thì lấy $autoAttrLimit thuộc tính đầu tiên để hiển thị
         */
        if (empty($this->columns) && $this->model)
        {
            $autoAttr      = array_slice($this->model->getAttributes(), 0, $this->autoAttrLimit);
            $this->columns = array_keys($autoAttr);
        }

        /**
         * Tạo Route
         */
        if ($this->route == '')
        {
            $this->route = Yii::app()->controller->id . '/' . Yii::app()->controller->action->id;
        }

        /**
         * Số phần tử hiển thị trên 1 trang
         */
        $this->currentLimit = isset($_GET['limit']) ? $_GET['limit'] : $this->limit;

        /**
         * Tạo đối tượng Controller hiện tại để xử lý tạo liên kết cho chính xác
         */
        $this->controller = Yii::app()->getController();

        /**
         * Xử lý kiểu sắp xếp mặc định
         */
        if (!$this->sort)
            $this->sort     = "id";
        if (!$this->sortType)
            $this->sortType = "desc";

        /**
         * Xử lý kiểu sắp xếp yêu cầu
         */
        if (!$this->noSort)
        {
            $sort                  = isset($_GET['sort']) ? explode(".", $_GET['sort']) : array();
            $this->currentSort     = isset($sort[0]) ? $sort[0] : "";
            $this->currentSortType = isset($sort[1]) ? $sort[1] : "";
        }
    }

    public function run()
    {
        // Điều kiện tìm kiếm
        $criteria = new CDbCriteria;

        /**
         * Sắp xếp theo các thông số truyền vào
         */
        if ($this->model->hasAttribute($this->currentSort) === TRUE)
            $criteria->order = "$this->currentSort $this->currentSortType";
        elseif ($this->model->hasAttribute($this->sort) === TRUE)
            $criteria->order = "$this->sort $this->sortType";

        $keySearch      = isset($_GET['key']) ? $_GET['key'] : '';
        $arr_key        = explode(' ', $keySearch);
        $criteria->with = $this->with;
        if ($keySearch != '' && $this->fieldSearch != '')
        {
            if (is_array($this->fieldSearch))
            {
                foreach ($this->fieldSearch as $searchField)
                {
                    foreach ($arr_key as $searchKey)
                    {
                        $criteria->compare($searchField, $searchKey, TRUE, 'OR');
                    }
                }
            }
            else
            {
                $criteria->addCondition("$this->fieldSearch like '%$keySearch%'");
            }
        }
        $criteria = $this->filter($criteria);

        // Phân trang
        $count           = $this->model->count($criteria);
        $pages           = new CPagination($count);
        $pages->route    = $this->route;
        $pages->pageSize = $this->currentLimit;
        $pages->applyLimit($criteria);

        $data = $this->model->findAll($criteria);
        $this->render('dataTable', array(
            'data'  => $data,
            'pages' => $pages,
        ));
    }

    private function filter($criteria)
    {
        if ($this->model->hasAttribute('language_id') === TRUE)
        {
            $language_id = Yii::app()->controller->lang_id;
            $criteria->addCondition("language_id = $language_id");
        }

        foreach ($_GET as $attr => $value)
        {
            if ($attr != 'key')
            {
                if ($this->model->hasAttribute($attr) === TRUE)
                {
                    $criteria->addCondition("$attr='$value'");
                }
            }
        }

        return $criteria;
    }

    /**
     * Hiển thị tên cột
     * @param mix $attribute : têm thuộc tính hoặc mảng thông tin thuộc tính
     * @return string : 
     */
    public function displayHeader($attribute = "")
    {
        $th = "";
        if ($attribute == '')
            return $th;

        // Nếu truyền lên tên thuộc tính thì lấy link sắp xếp
        if (is_string($attribute))
            $th .= $this->getSortLink($attribute);

        // Nếu truyền lên mảng thông tin về thuộc tính thì lấy thông tin về tên
        elseif (is_array($attribute))
            return isset($attribute['name']) ? $attribute['name'] : '';

        // Nếu mảng hiện đang được sắp xếp theo thuộc tính này thì hiển thị ký tự mũi tên
        if ($this->currentSort == $attribute)
        {
            $th .= ($this->currentSortType == 'desc') ? '&darr;' : '&uarr;';
        }
        return $th;
    }

    /**
     * Lấy link sắp xếp theo cột, khi bấm vào tên cột, thì bảng sẽ được sắp xếp
     * theo cột đấy, mặc định xếp theo kiểu từ nhỏ tới lớn, khi bấm lần thứ 2
     * sẽ sắp xếp theo chiều ngược lại
     * 
     * @param string $attribute Tên cột
     * @return string Link sắp xếp
     */
    public function getSortLink($attribute)
    {
        // Nếu bảng không hỗ trợ sắp xếp thì trả về tên thuộc tính
        if ($this->noSort)
            return $this->model->getAttributeLabel($attribute);

        // Lấy thông tin từ biển GET và chèn thông tin về sắp xếp bằng key sort
        $GET = $_GET;

        // Kiểm tra hiện tại đang được sắp xếp thế nào
        $sortType    = ($this->currentSortType == "desc") ? '' : '.desc';
        $GET['sort'] = $attribute . $sortType;

        // Tạo đường dẫn
        $url = $this->controller->createAbsoluteUrl($this->route, $GET);

        // Trả về link
        return CHtml::link($this->model->getAttributeLabel($attribute), $url);
    }

    public function displayItem($item, $attribute)
    {
        if (is_string($attribute))
        {
            $relationString = str_replace(".", "->", $attribute);
            return eval('return @$item->' . $relationString . ';');
        }
        elseif (is_array($attribute))
        {
            $data  = array('data' => $item);
            $value = isset($attribute['value']) ? $attribute['value'] : FALSE;
            if (is_string($value))
            {
                extract($data);
                return eval('return @' . $value . ';');
            }
        }
    }

    public function createActionButton($item)
    {
        $button = "";

        $updateUrl  = $this->getActionLink($item, 'update');
        $updateText = Yii::t('datatable', 'Update');
        $button .= " <a class='btn btn-mini' href='$updateUrl'>$updateText</a>";

        $deleteUrl  = $this->getActionLink($item, 'delete');
        $deleteText = Yii::t('datatable', 'Delete');
        $mess       = Yii::t('datatable', 'Do you want to remove this element?');
        $script     = 'return confirm("' . $mess . '")';
        $button .= " <a class='btn btn-inverse btn-mini' onclick='$script' href='$deleteUrl'>$deleteText</a>";

        return $button;
    }

    public function getActionLink($item, $action)
    {
        $route        = Yii::app()->controller->id;
        $params       = $_GET;
        $params['pk'] = $item->getPrimaryKey();

        return Yii::app()->controller->createUrl("$route/$action", $params);
    }

}

/** 
 * End file DataTable
 */
